home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
VARIABLE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-31
|
16KB
|
715 lines
/*
* Variabel setting and display
*/
#include "config.h"
import in_init;
import char /* string variables */
*decode_header_file,
*default_distribution,
*default_save_file,
*extra_mail_headers,
*extra_news_headers,
*header_lines,
*folder_directory,
included_mark[],
*mail_box,
*mail_record,
*mail_script,
*news_record,
*news_script,
*pager,
*patch_command,
printer[],
*save_counter_format,
*unshar_command,
*unshar_header_file;
import int /* boolean variables */
also_cross_postings,
also_subgroups,
auto_preview_mode,
compress_mode,
conf_append,
conf_auto_quit,
conf_create,
conf_dont_sleep,
conf_group_entry,
delay_redraw,
do_kill_handling,
dont_sort_articles,
dont_sort_folders,
dont_split_digests,
flow_control,
fmt_rptsubj,
include_art_id,
keep_rc_backup,
long_menu,
macro_debug,
mark_overlap,
monitor_mode,
nn_re_style,
novice,
quick_save,
save_report,
seq_cross_filtering,
shell_restrictions,
show_article_date,
show_current_time,
silent,
slow_mode,
use_mail_folders,
use_mmdf_folders,
use_newsrc,
use_visible_bell;
import int /* integer variables */
also_read_articles,
article_limit,
collapse_subject,
Columns,
Debug,
first_page_lines,
fmt_linenum,
Lines,
min_pv_window,
overlap,
preview_window,
re_layout,
retry_on_error,
slow_speed,
wrap_headers;
import char /* key strokes */
comp1_key,
comp2_key,
help_key,
erase_key,
delword_key,
kill_key;
#define V_STRING 0
#define V_BOOLEAN 1
#define V_INTEGER 2
#define V_KEY 3
#define V_SPECIAL 4
#define V_SAFE 0x80
#define V_INIT 0x40
struct variable_defs {
char *var_name;
char var_type;
char var_op;
char **var_addr;
} variables[] = {
"also-subgroups", V_BOOLEAN | V_INIT, 0, (char **)&also_subgroups,
"auto-preview-mode",V_BOOLEAN, 0, (char **)&auto_preview_mode,
"backup", V_BOOLEAN | V_INIT, 0, (char **)&keep_rc_backup,
"collapse-subject", V_INTEGER, 3, (char **)&collapse_subject,
"columns", V_INTEGER, 1, (char **)&Columns,
"comp1_key", V_KEY, 0, (char **)&comp1_key,
"comp2_key", V_KEY, 0, (char **)&comp2_key,
"compress", V_BOOLEAN, 0, (char **)&compress_mode,
"confirm-append", V_BOOLEAN, 0, (char **)&conf_append,
"confirm-auto-quit",V_BOOLEAN, 0, (char **)&conf_auto_quit,
"confirm-create", V_BOOLEAN, 0, (char **)&conf_create,
"confirm-entry", V_BOOLEAN, 0, (char **)&conf_group_entry,
"confirm-messages", V_BOOLEAN, 0, (char **)&conf_dont_sleep,
"cross-filter-seq", V_BOOLEAN, 0, (char **)&seq_cross_filtering,
"cross-post", V_BOOLEAN, 0, (char **)&also_cross_postings,
"date", V_BOOLEAN, 0, (char **)&show_article_date,
"debug", V_INTEGER, 0, (char **)&Debug,
"decode-header-file",V_STRING, 0, (char **)&decode_header_file,
"default-distribution",V_STRING, 0, (char **)&default_distribution,
"default-save-file",V_STRING, 3, (char **)&default_save_file,
"delay-redraw", V_BOOLEAN, 0, (char **)&delay_redraw,
"erase-key", V_KEY, 0, (char **)&erase_key,
"expert", V_BOOLEAN, 4, (char **)&novice,
"flow-control", V_BOOLEAN, 0, (char **)&flow_control,
"folder", V_STRING, 2, (char **)&folder_directory,
"fsort", V_BOOLEAN, 2, (char **)&dont_sort_folders,
"header-lines", V_STRING, 0, (char **)&header_lines,
"help-key", V_KEY, 0, (char **)&help_key,
"include-art-id", V_BOOLEAN, 0, (char **)&include_art_id,
"included-mark", V_STRING, 1, (char **)included_mark,
"kill", V_BOOLEAN, 0, (char **)&do_kill_handling,
"kill-key", V_KEY, 0, (char **)&kill_key,
"layout", V_INTEGER, 1, (char **)&fmt_linenum,
"limit", V_INTEGER, 2, (char **)&article_limit,
"lines", V_INTEGER, 1, (char **)&Lines,
"long-menu", V_BOOLEAN, 1, (char **)&long_menu,
"macro-debug", V_BOOLEAN, 0, (char **)¯o_debug,
"mail", V_STRING, 2, (char **)&mail_box,
"mail-format", V_BOOLEAN, 0, (char **)&use_mail_folders,
"mail-header", V_STRING, 0, (char **)&extra_mail_headers,
"mail-record", V_STRING, 2, (char **)&mail_record,
"mail-script", V_STRING | V_SAFE, 2, (char **)&mail_script,
"mark-overlap", V_BOOLEAN, 0, (char **)&mark_overlap,
"min-window", V_INTEGER, 1, (char **)&min_pv_window,
"mmdf-format", V_BOOLEAN, 0, (char **)&use_mmdf_folders,
"monitor", V_BOOLEAN, 0, (char **)&monitor_mode,
"news-header", V_STRING, 0, (char **)&extra_news_headers,
"news-record", V_STRING, 2, (char **)&news_record,
"news-script", V_STRING | V_SAFE, 2, (char **)&news_script,
"newsrc", V_BOOLEAN, 0, (char **)&use_newsrc,
"nn-re-style", V_BOOLEAN, 0, (char **)&nn_re_style,
"old", V_SPECIAL, 2, (char **)NULL,
"overlap", V_INTEGER, 0, (char **)&overlap,
"pager", V_STRING | V_SAFE, 3, (char **)&pager,
"patch-command", V_STRING | V_SAFE, 3, (char **)&patch_command,
"printer", V_STRING | V_SAFE, 1, (char **)printer,
"quick-save", V_BOOLEAN, 0, (char **)&quick_save,
"re-layout", V_INTEGER, 0, (char **)&re_layout,
"record", V_SPECIAL, 1, (char **)NULL,
"repeat", V_BOOLEAN, 0, (char **)&fmt_rptsubj,
"retry-on-error", V_INTEGER, 0, (char **)&retry_on_error,
"save-counter", V_STRING, 3, (char **)&save_counter_format,
"save-report", V_BOOLEAN, 0, (char **)&save_report,
"shell-restrictions", V_BOOLEAN|V_INIT, 0, (char **)&shell_restrictions,
"silent", V_BOOLEAN, 0, (char **)&silent,
"slow-mode", V_BOOLEAN, 0, (char **)&slow_mode,
"slow-speed", V_INTEGER, 0, (char **)&slow_speed,
"sort", V_BOOLEAN, 2, (char **)&dont_sort_articles,
"split", V_BOOLEAN, 4, (char **)&dont_split_digests,
"stop", V_INTEGER, 0, (char **)&first_page_lines,
"time", V_BOOLEAN, 0, (char **)&show_current_time,
"unshar-command", V_STRING | V_SAFE, 3, (char **)&unshar_command,
"unshar-header-file",V_STRING, 0, (char **)&unshar_header_file,
"visible-bell", V_BOOLEAN, 0, (char **)&use_visible_bell,
"window", V_INTEGER, 1, (char **)&preview_window,
"word-key", V_KEY, 0, (char **)&delword_key,
"wrap-header-margin",V_INTEGER, 2, (char **)&wrap_headers
};
#define TABLE_SIZE (sizeof(variables)/sizeof(struct variable_defs))
#define INT_VAR (*((int *)(var->var_addr)))
#define BOOL_VAR (*((int *)(var->var_addr)))
#define STR_VAR (*(var->var_addr))
#define CBUF_VAR ((char *)(var->var_addr))
#define KEY_VAR (*((unsigned char *)(var->var_addr)))
#define VAR_TYPE (var->var_type & 0xf)
static struct variable_defs *lookup_variable(variable)
char *variable;
{
register struct variable_defs *var;
register i, j, k, t;
i = 0; j = TABLE_SIZE - 1;
while (i <= j) {
k = (i + j) / 2;
var = &variables[k];
if ( (t=strcmp(variable, var->var_name)) > 0)
i = k+1;
else
if (t < 0)
j = k-1;
else
return var;
}
init_message("unknown variable: %s", variable);
return NULL;
}
set_variable(variable, on, val_string)
char *variable;
int on;
char *val_string;
{
int value;
register struct variable_defs *var;
if (strncmp(variable, "no", 2) == 0) {
on = !on;
variable += 2;
if (variable[0] == '-') variable++;
}
if ((var = lookup_variable(variable)) == NULL)
return 0;
if (!in_init && (var->var_type & (V_INIT | V_SAFE))) {
if (var->var_type & V_INIT) {
msg("'%s' can only be set in the init file", variable);
return 0;
}
if (shell_restrictions) {
msg("Restricted operation - cannot change");
return 0;
}
}
if (!on || val_string == NULL)
value = 0;
else
value = atoi(val_string);
switch (VAR_TYPE) {
case V_STRING:
switch (var->var_op) {
case 0:
STR_VAR = (on && val_string) ? copy_str(val_string) : (char *)NULL;
break;
case 1:
strcpy(CBUF_VAR, (on && val_string) ? val_string : "");
break;
case 2:
if (on) {
char exp_buf[FILENAME];
adjust(val_string);
if (val_string) {
if (expand_file_name(exp_buf, val_string))
STR_VAR = home_relative(exp_buf);
}
} else
STR_VAR = (char *)NULL;
break;
case 3:
if (!on || val_string == NULL) {
msg("Cannot unset string `%s'", variable);
break;
}
STR_VAR = copy_str(val_string);
break;
}
break;
case V_BOOLEAN:
if (val_string) on = strncmp(val_string, "off", 3);
switch (var->var_op) {
case 0:
BOOL_VAR = on;
break;
case 1:
BOOL_VAR = on;
return 1;
case 2:
if (BOOL_VAR == on) {
BOOL_VAR = !on;
if (!in_init) {
if (BOOL_VAR)
unsort_articles(1);
else
sort_articles();
return 1;
}
}
break;
case 4:
BOOL_VAR = !on;
break;
}
break;
case V_INTEGER:
switch (var->var_op) {
case 0:
case 1:
INT_VAR = value;
break;
case 2:
case 3:
if (!on) value = -1;
INT_VAR = value;
break;
}
return (var->var_op & 1);
case V_KEY:
switch (var->var_op) {
case 0:
if (val_string) {
if (*val_string) adjust(val_string + 1); /* #N is valid */
KEY_VAR = parse_key(val_string);
}
break;
}
break;
case V_SPECIAL:
switch (var->var_op) {
case 1:
if (val_string) {
adjust(val_string);
news_record = home_relative(val_string);
mail_record = news_record;
}
break;
case 2:
also_read_articles = on;
article_limit = (on && value > 0) ? value : -1;
break;
}
break;
}
return 0;
}
static adjust(str)
register char *str;
{
if (str == NULL) return;
while (*str && !isspace(*str) && *str != '#') str++;
*str = NUL;
}
disp_variables()
{
char *str, *key_name(), *pushed;
int i, b;
register struct variable_defs *var;
if (in_init) return;
pg_init(0, 1);
clrdisp();
pg_next();
so_printf("\1Variable settings:\1");
for (var = variables; var < &variables[TABLE_SIZE]; var++) {
pushed = var_on_stack(var) ? ">" : " ";
switch (VAR_TYPE) {
case V_STRING:
str = (var->var_op == 1) ? CBUF_VAR : STR_VAR;
if (str == NULL) str = "";
if (pg_next() < 0) goto out;
printf("%s %-20.20s = \"%s\"\n", pushed, var->var_name, str);
break;
case V_BOOLEAN:
if (pg_next() < 0) goto out;
b = BOOL_VAR;
if (var->var_op == 2 || var->var_op == 4) b = !b;
printf("%s %-20.20s %s\n", pushed, var->var_name, b ? "" : "= off");
break;
case V_INTEGER:
i = INT_VAR;
if (pg_next() < 0) goto out;
printf("%s %-20.20s = %d\n", pushed, var->var_name, i);
break;
case V_KEY:
if (pg_next() < 0) goto out;
printf("%s %-20.20s = %s\n", pushed, var->var_name, key_name(KEY_VAR));
break;
case V_SPECIAL:
switch (var->var_op) {
case 1:
break;
case 2:
if (also_read_articles) {
if (pg_next() < 0) goto out;
printf("%s %-20.20s = %d\n", pushed, var->var_name, article_limit);
}
break;
}
break;
}
}
out:
pg_end();
}
toggle_variable(variable)
char *variable;
{
register struct variable_defs *var;
if ((var = lookup_variable(variable)) == NULL) return;
if (VAR_TYPE != V_BOOLEAN) {
init_message("variable %s is not boolean", variable);
return;
}
BOOL_VAR = !BOOL_VAR;
}
test_variable(expr)
char *expr;
{
char *variable;
register struct variable_defs *var;
int res = -1;
variable = expr;
if ((expr = strchr(variable, '=')) == NULL)
goto err;
*expr++ = NUL;
if ((var = lookup_variable(variable)) == NULL) {
msg("testing unknown variable %s=%s", variable, expr);
goto out;
}
switch (VAR_TYPE) {
case V_BOOLEAN:
res = BOOL_VAR;
if (strcmp(expr, "on") == 0) break;
if (strcmp(expr, "off") == 0) {
res = !res;
break;
}
msg("boolean variables must be tested =on or =off");
break;
case V_INTEGER:
res = (INT_VAR == atoi(expr)) ? 1 : 0;
break;
default:
msg("%s: cannot only test boolean and integer variables", variable);
break;
}
out:
*--expr = '=';
err:
return res;
}
var_completion(path, index)
char *path;
int index;
{
static char *head, *tail = NULL;
static int len;
static struct variable_defs *var, *help_var;
if (index < 0) return 0;
if (path) {
head = path;
tail = path + index;
while (*head && isspace(*head)) head++;
if (strncmp(head, "no", 2) == 0) {
head += 2;
if (*head == '-') head++;
}
help_var = var = variables;
len = tail - head;
return 1;
}
if (index) {
list_completion((char *)NULL);
for (;; help_var++) {
if (help_var >= &variables[TABLE_SIZE]) {
help_var = variables;
break;
}
index = strncmp(help_var->var_name, head, len);
if (index < 0) continue;
if (index > 0) {
help_var = variables;
break;
}
if (list_completion(help_var->var_name) == 0) break;
}
fl;
return 1;
}
for (; var < &variables[TABLE_SIZE]; var++) {
if (len == 0)
index = 0;
else
index = strncmp(var->var_name, head, len);
if (index < 0) continue;
if (index > 0) break;
sprintf(tail, "%s ", var->var_name + len);
var++;
return 1;
}
return 0;
}
static struct var_stack {
struct var_stack *next;
struct variable_defs *v;
union {
int ivar;
int bool;
char key;
char *str;
} value;
} *var_stack = NULL, *vs_pool = NULL;
mark_var_stack()
{
register struct var_stack *vs;
if (vs_pool) {
vs = vs_pool;
vs_pool = vs->next;
} else {
vs = (struct var_stack *)calloc(1, sizeof(struct var_stack));
mem_check((char *)vs, 1, "var structure");
}
vs->next = var_stack;
var_stack = vs;
vs->v = NULL;
}
push_variable(variable)
char *variable;
{
register struct variable_defs *var;
register struct var_stack *vs;
if (strncmp(variable, "no", 2) == 0) {
variable += 2;
if (variable[0] == '-') variable++;
}
if ((var = lookup_variable(variable)) == NULL) {
msg("pushing unknown variable %s", variable);
return 0;
}
mark_var_stack();
vs = var_stack;
vs->v = var;
switch (VAR_TYPE) {
case V_STRING:
switch (var->var_op) {
case 0: /* if we update one of these variables, */
case 2: /* new storage will be allocated for it */
case 3: /* so it is ok just to save the pointer */
vs->value.str = STR_VAR;
break;
case 1: /* we free this memory when restored */
vs->value.str = copy_str(CBUF_VAR);
break;
}
break;
case V_BOOLEAN:
vs->value.bool = BOOL_VAR;
break;
case V_INTEGER:
vs->value.ivar = INT_VAR;
break;
case V_KEY:
vs->value.key = KEY_VAR;
break;
case V_SPECIAL:
msg("Cannot push pseudo variable %s", var->var_name);
break;
}
return 1;
}
restore_variables()
{
register struct variable_defs *var;
register struct var_stack *vs, *vs1;
vs = var_stack;
while (vs != NULL) {
if ((var = vs->v) == NULL) {
var_stack = vs->next;
vs->next = vs_pool;
vs_pool = vs;
return;
}
switch (VAR_TYPE) {
case V_STRING:
switch (var->var_op) {
case 0: /* only restore the string if changed; then we */
case 2: /* can also free the memory occupied by the */
case 3: /* 'new' value (if not NULL) */
if (STR_VAR != vs->value.str) {
if (STR_VAR != NULL) free(STR_VAR);
STR_VAR = vs->value.str;
}
break;
case 1: /* it fitted before, so it will fit againg */
strcpy(CBUF_VAR, vs->value.str);
free(vs->value.str);
break;
}
break;
case V_BOOLEAN:
BOOL_VAR = vs->value.bool;
break;
case V_INTEGER:
INT_VAR = vs->value.ivar;
break;
case V_KEY:
KEY_VAR = vs->value.key;
break;
case V_SPECIAL: /* these are not saved, so... */
break;
}
vs1 = vs->next;
vs->next = vs_pool;
vs_pool = vs;
vs = vs1;
}
var_stack = NULL;
}
static var_on_stack(var)
register struct variable_defs *var;
{
register struct var_stack *vs;
for (vs = var_stack; vs; vs = vs->next)
if (vs->v == var) return 1;
return 0;
}